
package com.jf.cloud.order.feign;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.jf.cloud.api.order.bo.UserScoreLogOrderBO;
import com.jf.cloud.api.order.constant.OrderStatus;
import com.jf.cloud.api.order.dto.CustomerRetainedDTO;
import com.jf.cloud.api.order.dto.FormExcelDTO;
import com.jf.cloud.api.order.dto.QueryOrderDTO;
import com.jf.cloud.api.order.feign.OrderFeignClient;
import com.jf.cloud.api.order.vo.*;
import com.jf.cloud.api.user.bo.UserOrderStatisticBO;
import com.jf.cloud.api.user.bo.UserOrderStatisticListBO;
import com.jf.cloud.api.user.dto.MemberReqDTO;
import com.jf.cloud.api.user.vo.UserManagerVO;
import com.jf.cloud.api.vo.EsPageVO;
import com.jf.cloud.common.constant.Constant;
import com.jf.cloud.common.database.dto.PageDTO;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.order.bo.EsOrderBO;
import com.jf.cloud.common.order.bo.OrderStatusBO;
import com.jf.cloud.common.order.constant.DeliveryType;
import com.jf.cloud.common.order.dto.OrderDTO;
import com.jf.cloud.common.order.dto.OrderSearchDTO;
import com.jf.cloud.common.order.dto.OrderVirtualInfoDTO;
import com.jf.cloud.common.order.vo.*;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.rocketmq.config.RocketMqConstant;
import com.jf.cloud.order.constant.RefundStatusEnum;
import com.jf.cloud.order.mapper.OrderItemMapper;
import com.jf.cloud.order.mapper.OrderMapper;
import com.jf.cloud.order.model.Order;
import com.jf.cloud.order.model.OrderItem;
import com.jf.cloud.order.service.*;
import io.swagger.v3.oas.annotations.Hidden;
import ma.glasnost.orika.MapperFacade;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zz
 * @date 2020/12/25
 */
@RestController
@Hidden
public class OrderFeignController implements OrderFeignClient {

    private final Logger logger = LoggerFactory.getLogger(OrderFeignController.class);

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private MapperFacade mapperFacade;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private OrderAnalysisService orderAnalysisService;
    @Autowired
    private OrderStatisticsService orderStatisticsService;
    @Autowired
    private RocketMQTemplate orderSettledShopTemplate;
    @Autowired
    private RocketMQTemplate orderReceiptTemplate;
    @Autowired
    private OrderVirtualInfoService orderVirtualInfoService;


    @Override
    public ServerResponseEntity<OrderAmountVO> getOrdersAmountAndIfNoCancel(List<Long> orderIds) {
        List<OrderStatusBO> orderStatus = orderService.getOrdersStatus(orderIds);
        if (CollectionUtil.isEmpty(orderStatus)) {
            return ServerResponseEntity.fail(ResponseEnum.ORDER_NOT_EXIST);
        }

        for (OrderStatusBO orderStatusBO : orderStatus) {
            // 订单已关闭
            if (orderStatusBO.getStatus() == null || Objects.equals(orderStatusBO.getStatus(), OrderStatus.CLOSE.value())) {
                return ServerResponseEntity.showFailMsg("订单已关闭");
            }
        }
        OrderAmountVO orderAmountVO = orderService.getOrdersActualAmount(orderIds);
        return ServerResponseEntity.success(orderAmountVO);
    }

    @Override
    public ServerResponseEntity<OrderAmountVO> getOrdersAmountAndCheckOrderStatus(List<Long> orderIds) {
        if (CollUtil.isEmpty(orderIds)) {
            return ServerResponseEntity.showFailMsg("订单id列表不能为空");
        }
        List<OrderStatusBO> orderStatus = orderService.getOrdersStatus(orderIds);
        if (CollectionUtil.isEmpty(orderStatus)) {
            return ServerResponseEntity.fail(ResponseEnum.ORDER_NOT_EXIST);
        }

        for (OrderStatusBO statusBO : orderStatus) {
            // 如果现在时间大于尾款时间，尾款时间已过期不能支付
            boolean dateCheck = DateUtil.compare(new Date(),statusBO.getBalanceEndTime()) > 0;
            // 订单状态不可支付尾款，请稍后再试
            if (statusBO.getStatus() == null || !Objects.equals(statusBO.getStatus(), OrderStatus.WAIT_BALANCE.value()) || dateCheck) {
                return ServerResponseEntity.showFailMsg("订单状态不可支付尾款，请稍后再试");
            }
        }
        OrderAmountVO orderAmountVO = orderService.getOrdersActualAmount(orderIds);
        return ServerResponseEntity.success(orderAmountVO);
    }

    @Override
    public ServerResponseEntity<List<OrderStatusBO>> getOrdersStatus(List<Long> orderIds) {
        List<OrderStatusBO> orderStatus = orderService.getOrdersStatus(orderIds);
        return ServerResponseEntity.success(orderStatus);
    }

    @Override
    public ServerResponseEntity<List<OrderSimpleAmountInfoBO>> getOrdersSimpleAmountInfo(List<Long> orderIds) {
        return ServerResponseEntity.success(orderService.getOrdersSimpleAmountInfo(orderIds));
    }

//    @Override
//    public ServerResponseEntity<List<OrderAmountInfoBO>> getOrdersAmountInfo(List<Long> orderIds) {
//        return ServerResponseEntity.success(orderService.getOrdersAmountInfo(orderIds));
//    }

    @Override
    public ServerResponseEntity<EsOrderBO> getEsOrder(Long orderId) {
        EsOrderBO esOrderBO = orderService.getEsOrder(orderId);
        return ServerResponseEntity.success(esOrderBO);
    }

    @Override
    public ServerResponseEntity<List<Long>> submit(ShopCartOrderMergerVO mergerOrder) {
        return ServerResponseEntity.success(orderService.submit(mergerOrder));
    }

    @Override
    public ServerResponseEntity<List<UserOrderStatisticVO>> countOrderByUserIds(QueryOrderDTO queryOrderDTO) {
        Long shopId = queryOrderDTO.getShopId() == null ? 0L : queryOrderDTO.getShopId();
        return ServerResponseEntity.success(orderStatisticsService.countOrderByUserIds(queryOrderDTO.getUserIds(), shopId));
    }

    @Override
    public ServerResponseEntity<List<UserManagerVO>> listOrderByUserIdsAndShopId(@RequestBody PageDTO pageDTO, List<Long> userIds, Long shopId, Integer sort) {
        return ServerResponseEntity.success(orderStatisticsService.listOrderByUserIdsAndShopId(pageDTO, userIds, shopId, sort));
    }

    @Override
    public ServerResponseEntity<OrderCountVO> countOrderByUserId(Long userId) {
        OrderCountVO orderCount = orderService.countNumberOfStatus(userId);
        return ServerResponseEntity.success(orderCount);
    }

    @Override
    public ServerResponseEntity<List<Long>> getOrderUserIdsBySearchDTO(OrderSearchDTO orderSearchDTO) {
        return ServerResponseEntity.success(orderStatisticsService.getOrderUserIdsBySearchDTO(orderSearchDTO));
    }

    @Override
    public ServerResponseEntity<List<Long>> listUserIdByPurchaseNum(Integer isPayed, Integer deleteStatus, Date startDate, Date endDate, Integer status, Long minNum, Long maxNum) {
        List<Long> userIds = orderStatisticsService.listUserIdByPurchaseNum(isPayed, deleteStatus, startDate, endDate, status, minNum, maxNum);
        return ServerResponseEntity.success(userIds);
    }

    @Override
    public ServerResponseEntity<List<Long>> listUserIdByAverageActualTotal(Integer isPayed, Integer deleteStatus, Date startDate, Date endDate, Integer status, Long minAmount, Long maxAmount) {
        List<Long> userIds = orderStatisticsService.listUserIdByAverageActualTotal(isPayed, deleteStatus, startDate, endDate, status, minAmount, maxAmount);
        return ServerResponseEntity.success(userIds);
    }
//
//    @Override
//    public ServerResponseEntity<List<CustomerRetainVO>> getTradeRetained(CustomerRetainedDTO customerRetainedDTO) {
//        List<CustomerRetainVO> list = orderAnalysisService.getTradeRetained(customerRetainedDTO);
//        return ServerResponseEntity.success(list);
//    }

    @Override
    public ServerResponseEntity<List<OrderProdEffectRespVO>> getProdEffectByDateAndProdIds(List<Long> spuIds, Long startTime, Long endTime) {
        return ServerResponseEntity.success(orderStatisticsService.getProdEffectByDateAndProdIds(spuIds,new Date(startTime),new Date(endTime)));
    }

    @Override
    public ServerResponseEntity<List<CustomerRetainVO>> getTradeRetained(CustomerRetainedDTO customerRetainedDTO) {
        List<CustomerRetainVO> list = orderAnalysisService.getTradeRetained(customerRetainedDTO);
        return ServerResponseEntity.success(list);
    }

    @Override
    public ServerResponseEntity<List<FlowOrderVO>> listFlowOrderByOrderIds(Collection<Long> orderIds) {
        if(CollUtil.isEmpty(orderIds)) {
            return ServerResponseEntity.success(new ArrayList<>());
        }
        List<FlowOrderVO> orderList = orderStatisticsService.listFlowOrderByOrderIds(orderIds);
        return ServerResponseEntity.success(orderList);
    }
    @Override
    public ServerResponseEntity<UserOrderStatisticBO> getPaidMemberByParam(MemberReqDTO param) {
        return ServerResponseEntity.success(orderStatisticsService.getPaidMemberByParam(param));
    }

    @Override
    public ServerResponseEntity<UserOrderStatisticListBO> getMemberPayData(MemberReqDTO param) {
        UserOrderStatisticListBO userOrderStatisticListBO = orderStatisticsService.getMemberPayData(param);
        return ServerResponseEntity.success(userOrderStatisticListBO);
    }

    @Override
    public ServerResponseEntity<Void> removeCacheTradeRetained(CustomerRetainedDTO customerRetainedDTO) {
        orderAnalysisService.removeCacheTradeRetained(customerRetainedDTO);
        return ServerResponseEntity.success();
    }

    @Override
    public ServerResponseEntity<Void> updateOrderItemBatchById(List<OrderItemVO> orderItemVOList) {
        List<OrderItem> orderItems = mapperFacade.mapAsList(orderItemVOList, OrderItem.class);
        for (OrderItem orderItem : orderItems) {
            orderItemMapper.update(orderItem);
        }
        return ServerResponseEntity.success();
    }
//
//    @Override
//    public ServerResponseEntity<List<EsOrderBO>> pageEsOrder(OrderSearchDTO orderSearchDTO) {
//        return ServerResponseEntity.success(orderService.pageEsOrder(orderSearchDTO));
//    }

    @Override
    public ServerResponseEntity<EsOrderBO> saveMongoAndGetEsInfo(Long orderId) {
        return ServerResponseEntity.success(orderService.saveMongoAndGetEsInfo(orderId));
    }
//
//    @Override
//    public ServerResponseEntity<Long> countOrderNum(OrderSearchDTO orderSearchDTO) {
//        return ServerResponseEntity.success(orderService.countOrderNum(orderSearchDTO));
//    }


    @Override
    public ServerResponseEntity<SendNotifyBO> getOrderDetailInfo(Long orderId) {
        return ServerResponseEntity.success(orderService.getOrderInfoByOrderId(orderId));
    }

    @Override
    public ServerResponseEntity<Integer> countNormalOrderByOrderIds(List<Long> orderIds) {
        int count;
        if (CollUtil.isEmpty(orderIds)) {
            count = 0;
        } else {
            count = orderMapper.countNormalOrderByOrderIds(orderIds);
        }
        return ServerResponseEntity.success(count);
    }

    @Override
    public ServerResponseEntity<List<SumAmountVO>> listSumDataByUserIds(List<Long> userIds) {
        return ServerResponseEntity.success(orderStatisticsService.listSumDataByUserIds(userIds));
    }

    @Override
    public ServerResponseEntity<Long> hasBuySuccessProd(Long spuId, Long userId) {
        return ServerResponseEntity.success(orderStatisticsService.hasBuySuccessProd(spuId, userId));
    }

    @Override
    public ServerResponseEntity<UserShoppingDataVO> calculateUserInShopData(Long userId) {
        return ServerResponseEntity.success(orderStatisticsService.calculateUserInShopData(userId));
    }
//
//    @Override
//    public ServerResponseEntity<List<OrderItemVO>> getOrderItems(List<Long> orderItemIds) {
//        return ServerResponseEntity.success(orderItemService.getOrderItems(orderItemIds));
//    }

//    @Override
//    public ServerResponseEntity<List<EsOrderBO>> getEsOrderList(List<Long> orderIds) {
//        return ServerResponseEntity.success(orderService.getEsOrderList(orderIds));
//    }

    @Override
    public ServerResponseEntity<Long> sumTotalDistributionAmountByOrderItem(List<OrderItemVO> orderItems) {
        // 订单总分销金额
        BigDecimal totalDistributionAmount = new BigDecimal(Constant.ZERO_LONG.toString());
        if (CollectionUtil.isNotEmpty(orderItems)) {
            for (OrderItemVO orderItem : orderItems) {
                if (Objects.isNull(orderItem.getDistributionUserId())) {
                    continue;
                }
                // 如果改订单项已经退款了的话，分销员的佣金就已经回退了，不需要继续算钱
                if (Objects.equals(orderItem.getRefundStatus(), RefundStatusEnum.SUCCEED.value()) || Objects.equals(orderItem.getRefundStatus(), RefundStatusEnum.PARTIAL_SUCCESS.value())) {
                    continue;
                }
                // 分销佣金
                if (orderItem.getDistributionAmount() != null && orderItem.getDistributionAmount() > 0) {
                    totalDistributionAmount = totalDistributionAmount.add(new BigDecimal(orderItem.getDistributionAmount().toString()));
                }
                // 上级分销佣金
                if (orderItem.getDistributionParentAmount() != null && orderItem.getDistributionParentAmount() > 0) {
                    totalDistributionAmount = totalDistributionAmount.add(new BigDecimal(orderItem.getDistributionParentAmount().toString()));
                }
            }
        }
        return ServerResponseEntity.success(totalDistributionAmount.longValue());
    }
//
//    @Override
//    public ServerResponseEntity<List<EsOrderBO>> getListBySettledOrOrderIds(Integer settled, List<Long> orderIds) {
//        return ServerResponseEntity.success(orderMapper.listBySettledOrOrderIds(settled,orderIds));
//    }

    @Override
    public ServerResponseEntity<List<OrderItemVO>> listOrderItemByOrderIds(List<Long> orderIds) {
        if (CollUtil.isEmpty(orderIds)) {
            return ServerResponseEntity.success(new ArrayList<>());
        }
        return ServerResponseEntity.success(orderItemMapper.listOrderItemByOrderIds(orderIds));
    }

    @Override
    public ServerResponseEntity<List<Long>> getInsightSpuIdsByDate(Integer begin, Integer size, Long shopId, Long startTime, Long endTime) {
        List<Long> spuIds = orderStatisticsService.getInsightSpuIdsByDate(begin, size, shopId, new Date(startTime), new Date(endTime));
        return ServerResponseEntity.success(spuIds);
    }

    @Override
    public ServerResponseEntity<List<UserScoreLogOrderBO>> getUserScoreLogDetail(List<Long> orderIds) {
        return ServerResponseEntity.success(orderItemService.getUserScoreLogDetail(orderIds));
    }

    @Override
    public ServerResponseEntity settledOrder(List<Long> orderIds) {
        // 开启事务消息，通知订单自己，开始往各个服务发送通知了
        TransactionSendResult transactionSendResult = orderSettledShopTemplate.sendMessageInTransaction(RocketMqConstant.ORDER_SETTLED_SHOP_TOPIC, new GenericMessage<>(orderIds), null);

        if (!Objects.equals(transactionSendResult.getLocalTransactionState(), LocalTransactionState.COMMIT_MESSAGE)) {
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
        return ServerResponseEntity.success();
    }

    @Override
    public ServerResponseEntity confirmOrder(List<Long> orderIds) {
        for (Long orderId : orderIds) {
            // 开启事务消息，通知订单自己，开始往各个服务发送通知了
            TransactionSendResult transactionSendResult = orderReceiptTemplate.sendMessageInTransaction(RocketMqConstant.ORDER_RECEIPT_TOPIC, new GenericMessage<>(orderId), null);

            if (!Objects.equals(transactionSendResult.getLocalTransactionState(), LocalTransactionState.COMMIT_MESSAGE)) {
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        }
        return ServerResponseEntity.success();
    }

    @Override
    public ServerResponseEntity<OrderActivityVO> getActivityOrderInfo(Long orderId) {
        OrderActivityVO orderVO = orderMapper.getActivityOrderInfo(orderId);
        if (Objects.isNull(orderVO)) {
            throw new LuckException("订单不存在, 订单id：" + orderId);
        }
        OrderItemVO orderItemVO = orderVO.getOrderItems().get(0);
        orderVO.setActivityId(orderItemVO.getActivityId());
        orderVO.setActivityType(orderItemVO.getActivityType());
        orderVO.setSpuId(orderItemVO.getSpuId());
        orderVO.setSkuId(orderItemVO.getSkuId());
        orderVO.setCount(orderItemVO.getCount());
        return ServerResponseEntity.success(orderVO);
    }

    @Override
    public ServerResponseEntity<Integer>  getUserBuyNumByActivityId(Long activityId, Integer activityType, Long spuId, Long userId) {
        Integer num = orderMapper.getUserBuyNumByActivityId(activityId, activityType, spuId, userId);
        if (Objects.isNull(num)) {
            num = 0;
        }
        return ServerResponseEntity.success(num);
    }

    @Override
    public ServerResponseEntity<List<OrderActivityVO>> getActivitySalesQuantity(List<Long> orderIds, Integer activityType) {
        List<OrderItemVO> orderItemList = orderItemMapper.listOrderItemByOrderIds(orderIds);
        List<Long> activityIds = orderItemList.stream()
                .filter(orderItemVO -> Objects.equals(orderItemVO.getActivityType(), activityType) && Objects.nonNull(orderItemVO.getActivityId()))
                .map(OrderItemVO::getActivityId)
                .collect(Collectors.toList());
        if (CollUtil.isEmpty(activityIds)) {
            return ServerResponseEntity.success();
        }
        List<OrderActivityVO> orderActivityList = orderStatisticsService.getActivitySalesQuantity(activityIds, activityType);
        if (CollUtil.isEmpty(orderActivityList)) {
            logger.error("套餐订单数量统计-无套餐统计结果， 套餐活动ids：{}", activityIds);
        }
        return ServerResponseEntity.success(orderActivityList);
    }

    @Override
    public ServerResponseEntity<List<EsOrderVO>> getUserByOrderIdList(List<Long> orderIds){
        return ServerResponseEntity.success(orderMapper.getUserByOrderIdList(orderIds));
    }

    @Override
    public ServerResponseEntity<Integer> countActivityOrderSale(Long activityId, Integer activityType) {
        return countActivitySkuSale(null, activityId, activityType);
    }

    @Override
    public ServerResponseEntity<Integer> countActivitySkuSale(Long skuId, Long activityId, Integer activityType) {
        if (Objects.isNull(activityId)) {
            throw new LuckException("活动id不能为空");
        }
        if (Objects.isNull(activityType)) {
            throw new LuckException("活动类型不能为空");
        }
        Long activityOrderSale = orderStatisticsService.countActivityOrderSale(skuId, activityId, activityType);
        return ServerResponseEntity.success(activityOrderSale.intValue());
    }

    @Override
    public ServerResponseEntity<List<OrderVO>> listOrderAndOrderItemByOrderIds(List<Long> orderIds) {
        if (CollUtil.isEmpty(orderIds)) {
            return ServerResponseEntity.success(new ArrayList<>());
        }
        List<OrderVO> orderVOS = orderMapper.listOrderAndOrderItemByOrderIds(orderIds);
        return ServerResponseEntity.success(orderVOS);
    }

    @Override
    public ServerResponseEntity<AccountOrderDetailVO> getAccountOrderDetail(Date startTime, Date endTime, String shopName, Long shopId) {
        AccountOrderDetailVO accountOrderDetail = orderStatisticsService.getAccountOrderDetail(startTime, endTime, shopName, shopId);
        return ServerResponseEntity.success(accountOrderDetail);
    }

    @Override
    public ServerResponseEntity<PageShopAccountOrderVO> listShopAccountDetail(Date startTime, Date endTime, String shopName, Integer pageSize, Integer pageNum) {
        PageShopAccountOrderVO list = orderStatisticsService.listShopAccountDetail(startTime, endTime, shopName, pageSize, pageNum);
        return ServerResponseEntity.success(list);
    }

    @Override
    public ServerResponseEntity<PageShopAccountOrderVO> listOrderPayInfo(Date startTime, Date endTime, Long shopId, String shopName, Integer pageSize, Integer pageNum) {
        PageShopAccountOrderVO list = orderStatisticsService.listOrderPayInfo(startTime, endTime, shopId, shopName, pageSize, pageNum);
        return ServerResponseEntity.success(list);
    }

    @Override
    public ServerResponseEntity<List<FormExcelDTO>> listFormExcelByParam(FormExcelParamVO formExcelParamVO) {
        List<FormExcelDTO> list = orderStatisticsService.listFormExcel(formExcelParamVO);
        return ServerResponseEntity.success(list);
    }

    @Override
    public ServerResponseEntity<List<Long>> getSoldNumRankByShopIdAndTime(String key, Long shopId, Integer time, Integer expireTime, Integer esRenovationSpuSort, Long primaryCategoryId) {
        return ServerResponseEntity.success(orderStatisticsService.addSoldNumRankCacheByShopIdAndTime(key,shopId,time,expireTime,esRenovationSpuSort, primaryCategoryId));
    }

    @Override
    public ServerResponseEntity<GroupInfoVO> getGroupInfoById(Long groupActivityId) {
        return ServerResponseEntity.success(orderStatisticsService.getGroupInfo(groupActivityId));
    }

    @Override
    public ServerResponseEntity<List<EsOrderVO>> getStationOrderBySeachDTO(OrderSearchDTO orderSearchDTO){
        orderSearchDTO.setDeliveryType(DeliveryType.STATION.value());
        EsPageVO<EsOrderVO> esPageVO = orderService.orderPage(orderSearchDTO);
        return ServerResponseEntity.success(esPageVO.getList());
    }

    @Override
    public ServerResponseEntity<Boolean> orderStationByOrderId(List<Long> orderIds, Long stationId) {
        return  ServerResponseEntity.success(orderService.orderStationByOrderId(orderIds, null, stationId));
    }

    @Override
    public ServerResponseEntity<List<OrderVO>> listStationOrder(OrderDTO orderDTO) {
        return ServerResponseEntity.success(orderService.listStationOrder(orderDTO));
    }

    @Override
    public ServerResponseEntity<Boolean> orderWriteOffByOrderId(OrderVirtualInfoDTO orderVirtualInfoDTO, Long orderId, Long statinoId) {
        Order order = orderService.getByOrderId(orderId);
        if (Objects.isNull(order) || order.getOrderMold() == 0) {
            // 订单不存在
            throw new LuckException("订单不存在");
        }
        Boolean aBoolean = orderVirtualInfoService.orderWriteOffByOrderId(orderVirtualInfoDTO, order, statinoId);
        return ServerResponseEntity.success(aBoolean);
    }
}
